//mod fairings;
mod errors;
mod models;
mod routes;
mod services;
mod utils;
use actix_web::{web, App, HttpServer};
use env_logger::Builder;
use log::LevelFilter;
//use deadpool_postgres::{ManagerConfig, RecyclingMethod, Runtime};
use actix_web::middleware::Logger;
use config::Environment;
use errors::MyError;
use routes::{
    delete_note, delete_note_note_category, get_note, get_note_category, get_notes, note_profiles,
    post_note_categories, post_notes,
};
use serde::Deserialize;
use tokio_postgres::NoTls;

#[derive(Debug, Default, Deserialize)]
pub struct ExampleConfig {
    pub server_addr: String,
    pub port: u16,
    pub pg: deadpool_postgres::Config,
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let mut builder = Builder::from_default_env();
    builder.filter_level(LevelFilter::Debug);
    builder.init();

    let config_ = config::Config::builder()
        .add_source(config::File::with_name("config.toml"))
        .add_source(Environment::with_prefix("note_book_api").separator("__"))
        .build()
        .unwrap();

    let config: ExampleConfig = config_.try_deserialize().map_err(MyError::ConfigError)?;
    println!("pg addr:{}", config.pg.host.as_ref().unwrap());
    let pool = config
        .pg
        .create_pool(None, NoTls)
        .map_err(MyError::CreatePoolError)?;

    println!("socket addr:{}:{}", config.server_addr.clone(), config.port);
    HttpServer::new(move || {
        App::new()
            .wrap(Logger::default())
            .wrap(Logger::new("%a %{User_Agent}i"))
            .app_data(web::Data::new(pool.clone()))
            .service(post_notes)
            .service(get_note)
            .service(delete_note)
            .service(get_notes)
            .service(post_note_categories)
            .service(delete_note_note_category)
            .service(get_note_category)
            .service(note_profiles)
    })
    .bind((config.server_addr.clone(), config.port))?
    .run()
    .await
}
